using System;
using System.Collections;
using System.Collections.Generic;
using System.Drawing;

namespace Nate.Shared
{
    public class Blackboard
    {
        #region GUI Blackboard. Holds values marked by GUI code and for the pathing code to read.
        public class GUI
        {
            public Point        Start;
            public Point        Dest;
            public Bitmap       Bmp;            //Nate-TODO: this should be a canvas-type handle
            public bool         AllowDiagonals;
            public bool         AllowVariable;
            public string       AlgorithmName;
            public string       SelectedOption;

            public bool         ReadyForPathing
            {
                get
                {
                    return !Start.IsEmpty &&
                           !Dest.IsEmpty &&
                            Bmp != null &&
                            AlgorithmName.Length > 0;
                }
            }

            public GUI()
            {
                Start          = Point.Empty;
                Dest           = Point.Empty;
                Bmp            = null;
                AlgorithmName  = "";
                SelectedOption = "";
                AllowDiagonals = false;
                AllowVariable  = false;
            }
            public GUI(GUI other)
            {
                Start          = other.Start;
                Dest           = other.Dest;
                Bmp            = other.Bmp;
                AlgorithmName  = other.AlgorithmName;
                SelectedOption = other.SelectedOption;
                AllowDiagonals = other.AllowDiagonals;
                AllowVariable  = other.AllowVariable;
            }

            #region operator overloads
            public static bool operator ==(GUI lhs, GUI rhs)
            {
                return lhs.Start          == rhs.Start &&
                       lhs.Dest           == rhs.Dest &&
                       lhs.Bmp            == rhs.Bmp &&
                       lhs.AlgorithmName  == rhs.AlgorithmName &&
                       lhs.SelectedOption == rhs.SelectedOption &&
                       lhs.AllowDiagonals == rhs.AllowDiagonals &&
                       lhs.AllowVariable  == rhs.AllowVariable;
            }
            public static bool operator !=(GUI lhs, GUI rhs)
            {
                return !(lhs == rhs);
            }
            public override bool Equals(object o)
            {
                return this == o as GUI;
            }
            public override int GetHashCode()
            {
                return Start.GetHashCode() ^ Dest.GetHashCode() ^ Bmp.GetHashCode() ^ AlgorithmName.GetHashCode() ^ SelectedOption.GetHashCode() ^ AllowDiagonals.GetHashCode() ^ AllowVariable.GetHashCode();
            }
            #endregion


        }
        #endregion
        
        #region Pathing Blackboard. Holds values marked by Pathing code and for the GUI code to read.
        public class Pathing
        {
            public List<Point>   Path;
            public Status        Status;
            public Utils.Options Options;

            public Pathing()
            {
                Path    = new List<Point>();
                Status  = Status.None;
                Options = null;
            }
            public Pathing(Pathing other)
            {
                Path    = other.Path;
                Status  = other.Status;
                Options = other.Options;
            }


            #region operator overloads
            public static bool operator ==(Pathing lhs, Pathing rhs)
            {
                return lhs.Path    == rhs.Path &&
                       lhs.Status  == rhs.Status &&
                       lhs.Options == rhs.Options;
            }
            public static bool operator !=(Pathing lhs, Pathing rhs)
            {
                return !(lhs == rhs);
            }
            public override bool Equals(object o)
            {
                return this == o as Pathing;
            }
            public override int GetHashCode()
            {
                return Path.GetHashCode() ^ Status.GetHashCode() ^ Options.GetHashCode();
            }
            #endregion
        }
        #endregion

        #region public Data and Properties
        public GUI     GuiBB            { get { return _gui; } }
        public Pathing PathingBB        { get { return _pathing; } }
        public bool    ReadyForPathing  { get { return GuiBB.ReadyForPathing; } }
        #endregion

        #region Constructors
        public Blackboard(Blackboard b)
        {
            _pathing = new Pathing(b.PathingBB);
            _gui = new GUI(b.GuiBB);
        }
        public Blackboard(Blackboard.Pathing pathing, Blackboard.GUI gui)
        {
            _pathing = new Pathing(pathing);
            _gui     = new GUI(gui);
        }
        public Blackboard(Blackboard.Pathing pathing)
        {
            _pathing = new Pathing(pathing);
            _gui     = new GUI();
        }
        public Blackboard(Blackboard.GUI gui)
        {
            _pathing = new Pathing();
            _gui     = new GUI(gui);
        }
        public Blackboard()
        {
            _gui     = new GUI();
            _pathing = new Pathing();
        }
        #endregion

        #region Private Data
        GUI     _gui;
        Pathing _pathing;
        #endregion
    }
}